from .models.task import Task
from .models.serializer import TaskSerializer
from apps.storage.models.pagination import MyPagination
from apps.storage.utils.general import json_response
from apps.storage.models.dataset import DataSet
from hte.error.handle import abort_on_error
from hte.error.models import HTEError
from apps.mlplatform.handle import handle_ml
from .views import FormatListCreateAPIView, FormatRetrivevAPIView, client_job
import json
import os
from django.http import FileResponse
from hte import settings
from .tasks import async_ml
from rest_framework.decorators import api_view


class TaskList(FormatListCreateAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer
    pagination_class = MyPagination


class TaskListMy(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username)
        return queryset


####fsch time12-26
class TaskListMyStatusUnc(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username, status=0)
        return queryset


class TaskListMyStatusRun(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username, status=1)
        return queryset


class TaskListMyStatusCom(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username, status=2)
        return queryset


###
###fsch time12-27
class TaskListMyAsc(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username).order_by('pub_data')
        return queryset


class TaskListMyDes(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username).order_by('-pub_data')
        return queryset


class TaskListMyStatusUncAsc(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username, status=0).order_by('pub_data')
        return queryset


class TaskListMyStatusUncDes(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username, status=0).order_by('-pub_data')
        return queryset


class TaskListMyStatusRunAsc(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username, status=1).order_by("pub_data")
        return queryset


class TaskListMyStatusRunDes(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username, status=1).order_by("-pub_data")
        return queryset


class TaskListMyStatusComAsc(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username, status=2).order_by("pub_data")
        return queryset


class TaskListMyStatusComDes(FormatListCreateAPIView):
    serializer_class = TaskSerializer
    pagination_class = MyPagination

    def get_queryset(self):
        queryset = Task.objects.filter(author=self.request.user.username, status=2).order_by("-pub_data")
        return queryset


class TaskDetail(FormatRetrivevAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer


def commit_task(request):
    if request.method == 'POST':
        data_json = json.loads(request.body)
        try:
            label = data_json['label']
        except KeyError:
            label = None
        dataset = DataSet.objects.get(pk=data_json['dataset'])
        dataset.ref_count += 1
        dataset.save()
        features = dataset.indexs
        if label:
            features.remove(label)
        task = Task.objects.create(title=data_json['title'],
                                   author=request.user.username,
                                   algorithm=data_json['algorithm'],
                                   params=data_json['params'],
                                   dataset_id=data_json['dataset'],
                                   task_type=data_json['task_type'],
                                   label=label,
                                   features=features)
        # handle_ml(task)
        # async_ml.delay(task.id)
        resp = client_job.submitWithFile(request.user.username, data_json['algorithm'],
                                         str(dataset.file), 'tasks.general.example:handle',
                                         task.algorithm, task.params, task.label, task.features)
        if json.loads(resp.content)['code'] == 0:
            task.task_id = json.loads(resp.content)['data']['task_id']
            task.status = 1
            task.save()
        serializer = TaskSerializer(data=data_json)
        if serializer.is_valid():
            return json_response(serializer.data)
        else:
            abort_on_error(HTEError.BAD_DATA)


@api_view(["GET", "POST", "DELETE"])
def file_download(request, pk):
    if request.method == 'GET':
        try:
            task = Task.objects.get(pk=pk)
        except Task.DoesNotExist:
            abort_on_error(HTEError.NOT_FOUND)
        filename = str(task.result_file)
        file_path = os.path.join(settings.MEDIA_ROOT, filename)
        response = FileResponse(open(file_path, 'rb'))
        response['Content-Disposition'] = "attachment; filename=%s" % filename
        return response
    else:
        abort_on_error(HTEError.METHOD_NOT_ALLOWED)
